home *** CD-ROM | disk | FTP | other *** search
/ Mac Magazin/MacEasy 43 / Mac Magazin and MacEasy Magazine CD - Issue 43.iso / Software / Entwickler / CCMArea / CCMArea Docs < prev    next >
Encoding:
Text File  |  1998-02-10  |  17.5 KB  |  211 lines  |  [TEXT/ttxt]

  1. Introduction
  2.  
  3. This package contains several classes designed for adding contextual menu support to PowerPlant applications. They were designed in an attempt to give the application a good amount of control over the menus' contents, and to satisfy Apple's interface recommendations. Below is a description of each class:
  4.  
  5. CCMArea
  6.  
  7. CCMArea is a mixin class, patterned somewhat after LDropArea (hence the name). The idea is that you write a pane class that also inherits from CCMArea. The constructor takes a pointer to another CCMArea, which should be your pane's superView or the surrounding window (which should be a CCMWindow or subclass thereof). If the object is being created from a PPob resource, you can set mSuperCMArea in FinishCreateSelf.
  8.  
  9. Modifications To Your Pane Class
  10.  
  11. - In ClickSelf, call CMClick (after checking if your pane is active and enabled). If the Contextual Menu Manager call IsShowContextualMenuClick returns true, CMClick will display the menu, handle the user selection, and return either cm_ItemChosen (if an application command was chosen) or cm_MenuDisplayed (if no command or a plugin command was chosen). Otherwise, it will return cm_Nothing, in which case you should handle the click normally.
  12. - In FinishCreateSelf, unless you have already given CCMArea's contructor a value for mSuperCMArea, you should call SetSuperCMArea. To find the closest owning view that inherits from CCMArea, you can call UCMArea::FindSuperCMArea. However, if you're sure you'll never want an owning obect adding commands, you can leave mSuperCMArea at NULL.
  13.  
  14. Methods You Should Override
  15.  
  16. BuildMenuSelf - In this method you add your commands to the given menu, and submenus if you desire (note that the Appearance Manager has added the call SetMenuItemHierarchicalID!). Also, you will need to use the Appearance Manager call SetMenuItemCommandID to add the command IDs to the menu items. The command ID you supply will be sent to the current Target via ProcessCommand.
  17.  
  18. For your menu-building convenience, UCMArea (see below) includes a static method AddCommandToMenu which searches the menu list for a matching command ID, appends the item's text to a given menu, and sets the new item's command ID. Normally, a command will not be added if it's disabled. To override this, you can pass true for inOverrideDisable. There is also AppendMenuCommand, which simply combines the toolbox functions AppendMenu and SetMenuItemCommandID, useful when you want to add commands that aren't in any menu in the menu bar.
  19.  
  20. GetSelectionDesc - If your pane contains data that should be available to contextual menu plug-ins, stuff it into the AEDesc passed to this method. By default, this will be passed up to the owning CCMArea, if any, so in some cases you may want to override it to make sure the AEDesc stays empty. If nothing else, you can provide an object descriptor of the window.
  21.  
  22. PreClick - This is called just before displaying the menu. It gives you a chance to perform any selection hiliting necessary to indicate what the context of the contextual menu is, and to make sure the command hierarchy is correct.
  23.  
  24. Optional Methods
  25.  
  26. PostClick - The counterpart to PreClick; after the menu selection (if any) is processed, PostClick is passed the mouse down event, the result of the contextual menu click (the value which will be returned by CMClick), and which application command was chosen, if any. This is useful if you need to do any visual cleaning up suck as unhiliting buttons.
  27.  
  28. CleanUpMenus - If you added submenus, this gives you the opportunity to remove them from the menu list and dispose of them.
  29.  
  30. AddSuperCommands - If you do not always want the superCMArea to add its commands, override this method and return false when appropriate.
  31.  
  32. DelayClick - "Delay click" refers to clicking the mouse button and holding it until the contextual menu appears. You can temporarily override the global delay click setting (UCMArea::GetDelayClick) for your pane in this method. There may be times and places, such as in a paint program, where delay click would be inappropriate.
  33.  
  34. HelpType - If you wish to provide help through Apple Guide or another system, override this method to return either kCMHelpItemAppleGuide or kCMHelpItemOtherHelp.
  35.  
  36. GetHelpItemString - If you have overridden HelpType to return kCMHelpItemOtherHelp, you should override this method to provide the name of the help item.
  37.     
  38. ShowHelp - When the user selects the Help command (enabled only if you have overridden HelpType), this method will be called. The default method does nothing; in the future I may add something to search for a guide file.
  39.  
  40. Other Notes
  41.  
  42. All IDs default to 999. If this conflicts with your application's resources, you can use CCMArea::SetMenuID, UCMArea::SetCursorID (before calling UCMArea::Initialize), and CCMWindow::SetCloseStringID.
  43.  
  44. UCMArea
  45.  
  46. UCMArea contains various utility functions used by the other classes to ensure that everything works right. When your application is starting up, you will need to call UCMArea::Initialize (unless you're using CCMApp).
  47.  
  48. There are also functions for getting and setting global values such as some resource IDs and delay click settings.
  49.  
  50. Two of the functions, EventMouseDown and AdjustCursor, should be called by any subclass of LEventDispatcher, just as the included CCMApp and StCMDialogHandler do. These functions take care of displaying the CM cursor, and displaying contextual menus for panes that do not inherit from CCMArea. UCMArea::AdjustCursor always displays the CM cursor if the control key is down and the cursor is over a window that inherits from CCMArea.
  51.  
  52. Clicks are handled like this:
  53. - A control-click in the drag area or a window control (close box, etc.) will display the window's menu.
  54. - A control-click in a pane that inherits from CCMArea will be handled normally- EventMouseDown returns false, indicating that the event should be passed on to LEventDispatcher::EventMouseDown.
  55. - A control-click in a pane that does not inherit from CCMArea (but the window does) will be passed to the pane's closest owning superView that does inherit from CCMArea. This may be the window itself.
  56. - Any contextual menu click in an inactive window will bring that window to the front, unless there is a modal dialog box.
  57.  
  58. Although I question the logic, UCMArea is consistent with the Finder in displaying the CM cursor over inactive windows when a modal dialog is present, even though no menu will be displayed.
  59.  
  60. CCMWindow
  61.  
  62. CCMWindow is a subclass of LWindow and CCMArea, which serves both as a basic example of how to use CCMArea, and as a starting point for windows that support contextual menus. Its BuildMenuSelf method adds a "Close Window" command (if the window has a close box and is not modal or floating). You can subclass this class to add additional commands, such as Save and Save As.
  63.  
  64. UCMArea uses RTTI to determine if a window is a subclass of CCMArea, so your existing window classes can be easily adapted- instead of converting your windows to CCMWindow subclasses, you can multiply inherit from CCMArea, and add the Close Window command yourself if you wish.
  65.  
  66. The file CCMArea.PPob has a STR# 999 resource which contains the string "Close Window". This was added to follow the Finder's example of using that phrase rather than simply "Close", which might be ambiguous in some situations. If you want to use a different resource ID, call UCMArea::SetCmdStringID.
  67.  
  68. CCMFloater
  69.  
  70. CCMFloater is a subclass of CCMWindow; its purpose is to have floating windows with a "Close Window" command that will close the right window, since using cmd_Close usually wouldn't close a floating window. Instead, you set the close command in Constructor (using your own command ID), and make sure that somewhere in your command chain that command is handled and the right floating window gets closed.
  71.  
  72. CCMDialogBox
  73.  
  74. CCMDialogBox is a subclass if LDialogBox. It mirrors the changes made by CCMWindow, and also uses CCMWindow's same command string resource.
  75.  
  76. CCMGADialog
  77.  
  78. CCMGADialogBox is just like CCMDialogBox, except it inherits from LGADialog instead of LDialogBox.
  79.  
  80. CCMApp
  81.  
  82. This class provides the necessary connections to UCMArea - it calls UCMArea::Initialize in the constructor, and it overrides EventMouseDown and AdjustCursor to pass those on to UCMArea.
  83.  
  84. CCMApp also handles the Appearance Manager event (appr/thme) that will be sent to applications when the theme is changed. In response to this event, CCMApp calls UCMArea::GetCMCursor to reload the contextual menu cursor in case the new theme has a different cursor. (Themes are scheduled to be implemented in "Allegro", the next major version of the Mac OS)
  85.  
  86. If you already have your application class based on another LApplication subclass (such as LDocApplication), you can imitate what CCMApp does. To handle the Theme Switch event, you will need to update your application's 'aedt' resource to include that event. You can copy the data from the resource in CCMArea.rsrc.
  87.  
  88. StCMDialogHandler
  89.  
  90. This is a subclass of StDialogHandler which reroutes EventMouseDown and AdjustCursor calls to UCMArea. You can simply substitute this class anywhere you use StDialogHandler.
  91.  
  92. CCMEditField
  93.  
  94. This class is provided partly as an example. It is a subclass of LEditField, and calls CMAdjustCursor and CMClick appropriately, and overrides BuildMenu to add Cut, Copy, Paste, and Select All to the menu. It also overrides GetSelection to provide either the selected text, or the entire text if nothing is selected.
  95.  
  96. Also, if you have Apple Data Detectors installed, this pane is an example of real ADD support! Even without the Contextual Menu Enabler extension (the one that adds ADD contextual menus to everything), if you type an Internet address into a CCMEditField and control-click on it, the Internet Address Detectors will recognize it.
  97.  
  98. CCMEditText
  99.  
  100. This is another example, based on the new Appearance class LEditText. It functions basically the same as CCMEditText.
  101.  
  102. Apple's Guidelines
  103.  
  104. This is a section from the Conextual Menus documentation, with a few of my comments:
  105.  
  106. When IsShowContextualMenuClick returns true, the user is attempting to display a Contextual Menu; your application should always display a CM in this case, even if it is a minimal menu. (Unless, of course, if it's outside a modal dialog)
  107.  
  108. If the CM-click is in an inactive window, that window should be brought to the front and immediately redrawn, if necessary. (UCMArea does this)
  109.  
  110. Next, your application should provide visual feedback indicating the item that was clicked upon. For example, a click on an icon should hilite the icon. CM-clicks on editable text should probably not eliminate the current selection. In this case, it is probably safe to assume that the user desires to invoke a CM for the selected area. (You can do this in PreClick)
  111.  
  112. Based upon the user’s click location, your application should generate a menu with the appropriate commands. Remember that Contextual Menus are supposed to contain the most frequently used commands. We recommend that you not add submenus nor disabled items in your CMs. (Note that the Finder uses submenus in its CMs!)
  113.  
  114. CM content for controls or window structure should be the same as that for unimportant window content. For example, if your application offers a CM with window specific commands (Close, Zoom, etc.) when the user clicks on unused portion of the window’s content rect, it should show these same commands on the CM for a close box or radio button. (UCMArea takes care of this stuff)
  115.  
  116. In addition to generating your own menu, you should also prepare an AEDesc which describes the item that your application is displaying a Contextual Menu for. This descriptor may contain an object specifier, or perhaps raw data (‘TEXT’, ‘PICT’, etc.). This descriptor will be passed to all Contextual Menu Plugins so they can provide additional functionality via the menu. (I have a complaint about how this was done- I think they should have used a Drag Manager-style flavored data system... whoops, where'd this soapbox come from?)
  117.  
  118. Release Notes
  119.  
  120. 1.0
  121. - Initial release
  122.  
  123. 1.0.1
  124. - Added optional, commented-out references to PowerPlant 1.8's UCursor
  125. - CCMArea::CMClick makes sure the menu has no trailing dividers
  126. - Added CCMArea::sCursorID and CCMWindow::sCloseStringID
  127.  
  128. 1.1
  129. - Added RTTI instead of using the window's userCon
  130. - Added CCMDialogBox
  131. - Changed CCMArea::GetSelectionDesec to pass it up to mSuperCMArea
  132. - The demo was rebulit with PowerPlant 1.8b1, using CCMDialogBox instead of CCMWindow for its window.
  133.  
  134. 1.2
  135. - CMClick calls ProcessCommand instead of ObeyCommand so that attachments can do their thing.
  136. - Folded the functionality of CCMAttachment and CCMEventAttachment (and some CCMArea things) into UCMArea. This was necessary to handle views that create subpanes on the fly, and it means you don't have to have all those attachments in your panes.
  137. - Nailed a few remaining cases that hadn't been updated to the RTTI method.
  138. - Added CCMEditText.
  139. - Added UCMArea.
  140. - CCMWindow and CCMDialogBox only add the Close Window command if they're reguler (not modal or floating) so you no longer have to override BuildMenuSelf for floating windows.
  141. - Added the modal dialog to the demo.
  142. - Updated CCMArea.CTYP so that CCMWindow and CCMDialogBox have the same default sizes as their parent classes.
  143.  
  144. 1.3
  145. - Added delay click
  146. - Moved CCMWindow::sCloseStringID to UCMArea::sCmdStringID
  147. - Cleaned up some minor mistakes which I hope didn't cause any headaches
  148.  
  149. 1.3.1
  150. - CCMArea::DelayClick now takes the SMouseDownEvent as a parameter
  151. - CCMArea::CMClick has three return values: cm_Nothing, cm_MenuDisplayed, and cm_ItemChosen
  152. - UCMArea::AdjustCursor returns false if the CM Manager is not present
  153. - UCMArea::AddCommandToMenu does a better job of determining if a command is enabled
  154. - Added CCMArea::PostClick
  155. - Added UCMArea::AppendMenuCommand
  156. - Added CCMFloater
  157. - Removed CCMArea::BalloonAvailable. The Mac OS 8 Toolbox Reference confirms that the "inBalloonAvailable" parameter of ContextualMenuClick wasn't really being used, and says that it should always be set to false.
  158. - Updated CCMEditText for PowerPlant 1.8.1. This version will not work with PowerPlant 1.8!
  159.  
  160. 1.3.2
  161. - Added CCMGADialog
  162. - A control-click in a window title bar will no longer bring that window to the front if it is behind a modal dialog
  163. - Fixed a problem where control-clicking on certain panes outside of a modal dialog would display a menu instead of beeping
  164. - CCMEditText and CCMEditField check if they're active and enabled before calling CMClick
  165. - Added theme switching support
  166.  
  167. Last Little Bits
  168.  
  169. Files in the package
  170.  
  171. The file CCMArea.CTYP contains custom type information for CCMWindow, CCMFloater, CCMDialogBox, CCMGADialog, CCMEditField and CCMEditText. It should be placed in Constructor's Custom Types folder. To make a new CCMWindow or CCMDialogBox, drag the class (in the Windows category) from the catalog window to your project window - it won't be available from the Creat New Resource dialog.
  172.  
  173. The demo app is PowerPC only; my apologies to those with 68k machines. I didn't bother including the source and project for it because it's so simple - just a couple of modifications to the basic PP app stationery, using a subclass of CCMApp. Besides, you can still open it up in Constructor (be sure to install CCMArea.CTYP first).
  174.  
  175. CCMArea.PPob contains the CM cursor and the "Close Window" command.
  176.  
  177. CCMArea.rsrc contains an 'aedt' resource, which maps the Theme Switch event to event ID 'thme', which is defined as ae_ThemeSwitch in UCMArea.h.
  178.  
  179. Backward compatibility
  180.  
  181. I'm contemplating adding fake contextual menus for System 7 compatibility. The problem is that I depend on being able to set menu item command IDs (a new feature with the Appearance Manager), so I'll have to find a way around that.
  182.  
  183. Contextual Menus SDK
  184.  
  185. If you haven't found the Contextual Menus SDK, you can download it with this URL:
  186.   http://devworld.apple.com/ngs/lpp/adrpub/docs/MacOS8/Contextual_Menus.sea.hqx
  187.  
  188. More up-to-date documentation, but without the library, header files, and sample CM plugin, are at:
  189.   http://gemma.apple.com/dev/techsupport/insidemac/MacOS8ToolboxRef/index.html
  190.  
  191. Look Mom, No Hands!
  192.  
  193. Tools and Toys' utility Look Mom, No Hands!, which lets users access contextual menus without using the control key, doesn't seem to affect applications other than the Finder, so it will not affect applications that use CCMArea. It only seems to work in certain parts of the Finder, so there doesn't seem to be anything I can do about making CCMArea compatible. Anyway, you can still use CCMArea's delay click option.
  194.  
  195. I contacted the author of Look Mom, No Hands, and he said that in the upcoming version 2.0 there will be a Gestalt selector for detecting LMNH. Once that's in place, I'll have UCMArea::Initialize check for it.
  196.  
  197. The Catch
  198.  
  199. As far as licensing and fees go, here's the policy: for freeware and shareware programs, I ask that you send me a full working copy of your program, or the price thereof. For commercial stuff, contact me and we'll work something out. If you help me to improve the classes, I'm willing to lower the price. And in all programs I would like credit in the documentation and/or the about box.
  200.  
  201. This document was written using Espy Sans and Espy Serif. My apologies if you don't have these fonts and it looks ugly.
  202.  
  203. If you have any questions or comments, don't be afraid to e-mail me. I tend to be very responsive, and I want my stuff to be as good as I can make it. As events warrant, I'll try to keep my web page up-to-date on updates.
  204.  
  205. If you want to see an example of CCMArea in action, check out the control panel in my StuffCM package, and version 1.1 of my icon editor, Icon Machine (see my shareware page, below).
  206.  
  207. Name: David Catmull
  208. E-Mail: dathorc@kagi.com
  209. Web: http://bounce.to/dathorc
  210. CCMArea page: http://www.kagi.com/dathorc/ccmarea.html
  211. Shareware page: http://www.kagi.com/dathorc/index.html